package com.nineclock.system.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.sms.AliyunSmsUtils;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.PhoneNumCheckUtils;
import com.nineclock.model.pojo.SysCompanyUser;
import com.nineclock.model.pojo.SysUser;
import com.nineclock.system.mapper.SysCompanyUserMapper;
import com.nineclock.system.mapper.SysUserMapper;
import com.nineclock.system.service.SmsService;
import com.nineclock.system.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class SmsServiceImpl implements SmsService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private AliyunSmsUtils smsUtils;

    @Autowired
    private SysUserService sysUserService;

    @Override
    public void createSmsCode(String mobile, String type) {
        if (StringUtils.isEmpty(mobile) || StringUtils.isEmpty(type)) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //判断手机号是否可用
        if (!PhoneNumCheckUtils.isPhoneLegal(mobile)) {
            throw new NcException(ResponseEnum.INVALID_PHONE_NUMBER);
        }
        //如果是注册,判断手机号是否存在
        if (type.equals("2")) {
            Boolean flag = checkExists(mobile);

            if (flag) {
                throw new NcException(ResponseEnum.USER_MOBILE_EMAIL_EXISTS);
            }
        } else {
            //其他情况,手机号必须存在
            Boolean flag = checkExists(mobile);

            if (!flag) {
                throw new NcException(ResponseEnum.USER_NOT_REGISTER);
            }
        }

        //随机生成验证码
        String randomCode = RandomUtil.randomNumbers(6);

        //发送短信验证码, 调用ali
        /*Boolean result = smsUtils.sendSMS(mobile, randomCode);
        if (!result) {
            throw new NcException(ResponseEnum.SEND_MESSAGE_ERROR);
        }*/
        //redis中存储短信验证码
        String key = getPrefix(type) + mobile;

        redisTemplate.boundValueOps(key).set(randomCode, 5, TimeUnit.MINUTES);

        log.info("成功发送验证码, 具体信息 : " + mobile + ", " + randomCode);

    }
    @Autowired
    SysCompanyUserMapper userMapper;

    @Override
    public Boolean checkExists(String mobile) {
        LambdaQueryWrapper<SysCompanyUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysCompanyUser::getMobile, mobile);
        Integer count = userMapper.selectCount(queryWrapper);
        return count != 0;
    }

    @Override
    public Boolean verifySms(String mobile, String checkcode, String type) {
        if (StringUtils.isEmpty(mobile)||StringUtils.isEmpty(checkcode)||StringUtils.isEmpty(type)) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        String key = getPrefix(type) + mobile;

        Object realCode = redisTemplate.boundValueOps(key).get();
        if (realCode.equals(checkcode)){
            return true;
        }
        return false;


    }

    /**
     * 删除验证码
     * @param mobile
     * @param type
     */
    @Override
    public void deleteSmsCode(String mobile, String type) {
        String redisKey = this.getPrefix(type)+mobile;
        redisTemplate.delete(redisKey);
    }

    private String getPrefix(String type) {
        String prefix = "";
        switch (type) {
            case SMSConstant.SMS_TYPE_LOGIN:
                prefix = SMSConstant.SMS_TYPE_LOGIN;
                break;
            case SMSConstant.SMS_TYPE_REGISTER:
                prefix = SMSConstant.SMS_TYPE_REGISTER;
                break;
            case SMSConstant.SMS_TYPE_CHANGE_MANAGER:
                prefix = SMSConstant.SMS_TYPE_CHANGE_MANAGER;
                break;
            case SMSConstant.SMS_TYPE_RESET_PASSWORD:
                prefix = SMSConstant.SMS_TYPE_RESET_PASSWORD;
                break;
            default:
                break;
        }
        return prefix;
    }
}
